﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using BookShop.DAL;
using BookShop.DTO;
using BookShop.Library.Common;
using BookShop.Library.Constant;

namespace BookShop.BLL
{
    public class CustomerService
    {
        public static Customer Add(Customer customer, out string messages)
        {
            using (var repository = new CustomerRepository())
            {
                var validUserName = customer.Username.Trim().Contains(' ');
                var duplicateEmailCount = repository.FindAll(c => c.Email.ToLower().Equals(customer.Email.ToLower())).Count();
                var duplicateUsernameCount =
                    repository.FindAll(c => c.Username.ToLower().Equals(customer.Username.ToLower())).Count();
                messages = string.Empty;
                if (duplicateEmailCount == 0 && duplicateUsernameCount == 0)
                {
                    if (!string.IsNullOrWhiteSpace(customer.Password))
                    {
                        customer.Password = CommonFunction.EncryptString(customer.Password);
                    }
                    return repository.Add(customer);
                }
                if (duplicateEmailCount != 0)
                {
                    messages += AlertMessage.ExistedEmail + ",";
                }
                if (duplicateUsernameCount != 0)
                {
                    messages += AlertMessage.ExistedUsername + ",";
                }
                if (!validUserName)
                {
                    messages += AlertMessage.InvalidInput + ",";
                }
                messages = messages.TrimEnd(',');
                return null;
            }
        }
        public static bool Delete(long customerId)
        {
            using (var repository = new CustomerRepository())
            {
                var customer = GetById(customerId);
                if (customer == null)
                {
                    return false;
                }
                customer.Status = CustomerStatus.Inactive;
                customer = repository.Update(customer);
                return customer != null;
            }
        }
        public static List<Customer> GetAll()
        {
            using (var repository = new CustomerRepository())
            {
                return repository.FindAll(c => c.Status == CustomerStatus.Active).ToList();
            }
        }
        public static Customer GetById(long customerId)
        {
            using (var repository = new CustomerRepository())
            {
                return repository.Find(c => c.Id == customerId);
            }
        }
        public static Customer Login(string username, string password)
        {
            using (var repository = new CustomerRepository())
            {
                password = CommonFunction.EncryptString(password);
                return repository.Find(m => m.Username.Equals(username) && m.Password.Equals(password));
            }
        }
        public static List<Customer> Search(long? customerId, string email, string fromBirthdate, string toBirthdate,
            string address, string phone, string fullName, int? status, int page, int pageSize,
            out int count)
        {
            var repository = new CustomerRepository();
            var returnList = new List<Customer>();
            if (customerId.HasValue)
            {
                var customer = GetById(customerId.Value);
                if (customer != null)
                {
                    returnList.Add(customer);
                }
            }
            else
            {
                returnList = repository.GetAll().ToList();
                if (!string.IsNullOrWhiteSpace(email))
                {
                    returnList = returnList.FindAll(c => c.Email.ToLower().Contains(email.Trim().ToLower()));
                }
                DateTime newFromBirthdate;
                var isValidFromBirthdate = DateTime.TryParse(fromBirthdate, CultureInfo.CreateSpecificCulture("vi-VN"),
                    DateTimeStyles.None, out newFromBirthdate);
                DateTime newToBirthdate;
                var isValidToBirthdate = DateTime.TryParse(toBirthdate, CultureInfo.CreateSpecificCulture("vi-VN"),
                    DateTimeStyles.None, out newToBirthdate);
                if (isValidFromBirthdate && isValidToBirthdate)
                {
                    returnList =
                        returnList.FindAll(a => a.Birthdate >= newFromBirthdate && a.Birthdate <= newToBirthdate);
                }
                if (isValidFromBirthdate && !isValidToBirthdate)
                {
                    returnList =
                        returnList.FindAll(a => a.Birthdate >= newFromBirthdate);
                }
                if (!isValidFromBirthdate && isValidToBirthdate)
                {
                    returnList =
                        returnList.FindAll(a => a.Birthdate <= newToBirthdate);
                }
                if (!string.IsNullOrWhiteSpace(address))
                {
                    returnList = returnList.FindAll(c => c.Address.ToLower().Contains(address.Trim().ToLower()));
                }
                if (!string.IsNullOrWhiteSpace(phone))
                {
                    returnList = returnList.FindAll(c => c.Phone.ToLower().Contains(phone.Trim().ToLower()));
                }
                if (!string.IsNullOrWhiteSpace(fullName))
                {
                    returnList = returnList.FindAll(c => c.FullName.ToLower().Contains(fullName.Trim().ToLower()));
                }
                if (status.HasValue)
                {
                    returnList = returnList.FindAll(c => c.Status == status.Value);
                }
            }
            count = returnList.Count;
            return returnList.Skip((page - 1) * pageSize).Take(pageSize).ToList();
        }
        public static Customer Update(Customer customer, out string messages)
        {
            using (var repository = new CustomerRepository())
            {
                messages = string.Empty;
                if (customer != null)
                {
                    var duplicateEmailCount = repository.FindAll(c => c.Id != customer.Id && c.Email.ToLower().Equals(customer.Email.ToLower())).Count();
                    if (duplicateEmailCount == 0)
                    {
                        return repository.Update(customer);
                    }
                    messages += AlertMessage.ExistedEmail;
                    return null;
                }
                messages += AlertMessage.NotFoundObject + ",";
                messages = messages.TrimEnd(',');
                return null;
            }
        }
    }
}
